home *** CD-ROM | disk | FTP | other *** search
/ ShareWare OnLine 2 / ShareWare OnLine Volume 2 (CMS Software)(1993).iso / prog / ixe130.zip / IXEBLIT.C < prev    next >
C/C++ Source or Header  |  1993-05-09  |  5KB  |  176 lines

  1. /*
  2.     Filename    :   ixeblit.c
  3.     Author      :   Ray E. Bornert II
  4.     Date        :   1993-APR-09
  5.  
  6.     Copyright (C) 1993 HixoxiH Software.  All rights reserved.
  7. */
  8.  
  9. //compile line:
  10. // bcc -ml -c -B ixeblit.c
  11.  
  12. #include "ixeblit.h"
  13. #include <dos.h>
  14.  
  15. /*
  16. This routine good on 80386's and above for all IXE supported video modes
  17. */
  18. asm P386
  19. void ixeBlitXY32               //very fast and exclusive
  20. (
  21.     unsigned char *dest,       //MUST be paragraph aligned for planar mode
  22.     void          *ixeCode,    //address of the precompiled icon
  23.     unsigned long DestWidth,   //byte width of destination buffer
  24.     unsigned long x,           //horizontal coordinate based at 0
  25.     unsigned long y            //vertical coordinate based at 0
  26. )
  27. {
  28. asm {
  29.     push    ds;                //save segment
  30.     pushad;
  31.  
  32.     xor     edi,edi;           //edi=0
  33.     lds     di,dest;           //point ds:di to dest
  34.  
  35.     mov     ebx,DestWidth;     //load the destination width
  36.     mov     eax,y;             //load the y coordinate
  37.     mul     ebx;               //
  38.     add     eax,x;             //
  39.     add     edi,eax;           //offset += y*DestWidth+x
  40.     call    dword ptr ixeCode; //goto ixe code
  41.  
  42.     popad;
  43.     pop     ds;                //restore segment
  44.     }
  45. }
  46.  
  47. /*
  48. This routine good on 80286's and above for all IXE supported video modes
  49. where screen size in pixels is less than 65536.
  50.  
  51. NOTE:
  52. This routine SHOULD NOT be used with video modes
  53. where Pixel ScreenWidth * Pixel ScreenHeight > 65536
  54. Mode 320x200 is okay because 320*200=64000 and is less than 65536
  55. The reason for all of this is that 16bit unsigned math wraps at 65535
  56. For example in mode 320x240 the offset for screen coordinate y=204,x=256
  57. is 320*204+256=65536 but a 16bit unsigned value with all bits on is 65535
  58. If the cpu is allowed to perform 320*204+256 the result will be zero and
  59. 320*204+257 will equal 1 and so forth and so on. 16bit math wraps at 65535.
  60. If you are using a video mode with a screen size > 65535 and
  61. you must use 16 bit code then you should use the slower yet reliable
  62. plain jane ixeBlitXY below.
  63. */
  64. asm P286
  65. void ixeBlitXY16               //fast and restricted
  66. (
  67.     unsigned char *dest,       //MUST be paragraph aligned for planar mode
  68.     void          *ixeCode,    //address of the precompiled icon
  69.     unsigned short DestWidth,  //byte width of destination buffer
  70.     unsigned short x,          //horizontal coordinate based at 0
  71.     unsigned short y           //vertical coordinate based at 0
  72. )
  73. {
  74. asm {
  75.     push    ds;                //save segment
  76.     pusha;
  77.  
  78.     xor     di,di;             //edi=0
  79.     lds     di,dest;           //point ds:di to dest
  80.  
  81.     mov     bx,DestWidth;      //load the destination width
  82.     mov     ax,y;              //load the y coordinate
  83.     mul     bx;                //
  84.     add     ax,x;              //
  85.     add     di,ax;             //offset += y*DestWidth+x
  86.     call    dword ptr ixeCode; //goto ixe code
  87.  
  88.     popa;
  89.     pop     ds;                //restore segment
  90.     }
  91. }
  92.  
  93. /*
  94. This routine good on 80286's and above for all IXE supported video modes
  95. */
  96. asm P286
  97. void ixeBlitXY                 //slowest and most generic
  98. (
  99.     unsigned char *dest,       //MUST be paragraph aligned for planar mode
  100.     void          *ixeCode,    //address of the precompiled icon
  101.     unsigned int DestWidth,    //byte width of destination buffer
  102.     unsigned int x,            //horizontal coordinate based at 0
  103.     unsigned int y             //vertical coordinate based at 0
  104. )
  105. {
  106.     //this stuff is slow but we gotta do it to be generic
  107.     unsigned short s=FP_SEG(dest);
  108.     unsigned short o=FP_OFF(dest);
  109.     unsigned long u,adjust;
  110.     u=(long)o+((long)y*(long)DestWidth+(long)x);
  111.     if (*((unsigned short *)ixeCode) == 0xCF8B)
  112.         adjust=64; else
  113.         adjust=16;
  114.     o = (unsigned short)(u%adjust);
  115.     s+= (u/adjust);
  116.     dest = (unsigned char *)MK_FP(s,o);
  117.  
  118. asm {
  119.     push    ds;
  120.     pusha;
  121.     lds     di,dest;
  122.     mov     bx,DestWidth;
  123.     call    dword ptr ixeCode;
  124.     popa;
  125.     pop     ds;
  126.     }
  127. }
  128.  
  129. /*
  130. The code below is desinged to sidestep Interrupt 13 which occurs when the
  131. CPU encounters the following:
  132.     mov word ptr [FFFFh], <any 16bit or 32bit operand> or
  133.     mov dword ptr [FFFFh], <any 16bit or 32bit operand> or
  134.     mov dword ptr [FFFEh], <any 32bit operand> or
  135.     mov dword ptr [FFFDh], <any 32bit operand>
  136. */
  137. #ifdef __cplusplus
  138.     #define __CPPARGS ...
  139. #else
  140.     #define __CPPARGS
  141. #endif
  142. void interrupt ( *oldInt13)(__CPPARGS);
  143. unsigned char far newInt13[256]=
  144. {
  145.     0x89,0xDA,       //mov dx,bx
  146.     0x5B,            //pop bx
  147.     0x07,            //pop es
  148.     0x26,            //es:
  149.     0x80,0x3F,0x66,  //cmp byte ptr [bx],66
  150.     0x75,0x03,       //jne $+5
  151.     0x83,0xC3,0x02,  //add bx,2
  152.     0x83,0xC3,0x06,  //add bx,6
  153.     0x06,            //push es
  154.     0x53,            //push bx
  155.     0x89,0xD3,       //mov bx,dx
  156.     0xCF             //iret
  157. };
  158.  
  159. /*
  160. This routine saves the current Interrupt Vector for Interrupt 13
  161. and then sets Interrupt Vector 13 to point to newInt13 above.
  162. */
  163. void disableInt13(void)
  164. {
  165.     oldInt13 = getvect(13);
  166.     setvect(13,(void interrupt (*)(__CPPARGS))  newInt13);
  167. }
  168.  
  169. /*
  170. This routine restores the original value of Interrupt Vector 13
  171. */
  172. void enableInt13(void)
  173. {
  174.     setvect(13,oldInt13);
  175. }                                                                 
  176.